package edu.corn.job.core.processor.adapter;

import edu.corn.job.core.context.JobRunningContext;
import edu.corn.job.core.engine.JobEngine;
import edu.corn.job.core.processor.AbstractJobProcessor;
import edu.corn.job.core.processor.adapter.factory.JobAdapterFactory;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import static edu.corn.job.core.processor.adapter.handler.CheckAndDoneHandler.DONE;

/**
 * 只有组合或者是级联的job，有子的概念。PhaseJob没有子的概念。
 */
public class CompositeJopAdapter extends AbstractJobAdapter {

    protected String FINAL_JOB = "END_JOB";

    /**
     * 当前执行到的job。
     */
    protected String curJob;

    /**
     * 子job map
     */
    protected transient LinkedHashMap<String, JobAdapter> jobMap = new LinkedHashMap<>();

    public CompositeJopAdapter(AbstractJobProcessor processor, JobEngine jobEngine) {
        super(processor, jobEngine);
        // 初始化
        for (AbstractJobProcessor child : job.children()) {
            JobAdapter adapter = JobAdapterFactory.getAdapter(child,jobEngine);
            jobMap.put(child.getName(), adapter);
        }
        jobMap.put(FINAL_JOB, null);
        curJob = jobMap.entrySet().iterator().next().getKey();
    }

    /**
     * 找到当前执行的job。
     *
     * @return
     */
    protected Iterator<Map.Entry<String, JobAdapter>> iterator(String jobName) {
        Iterator<Map.Entry<String, JobAdapter>> iterator = jobMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, JobAdapter> entry = iterator.next();
            if (entry.getKey().equals(jobName)) {
                return iterator;
            }
        }
        return iterator;
    }






    @Override
    public boolean doJobInternal(JobRunningContext context) {
        Iterator<Map.Entry<String, JobAdapter>> iterator = iterator(curJob);
        while (iterator.hasNext()) {
            // TODO 是否会跳过一个job。
            JobAdapter adapter = iterator.next().getValue();

            // 执行子job。
            try {
                adapter.executeJob(context);
            } catch (Throwable e) {
                // 尝试让job自己处理异常。
                if (!job.handleException(e, context)) {
                    throw e;
                }
            }
        }

        // 当前job检查是否符合预期。
        String mayRetry = job.checkAndDone(context);
        if (!Objects.equals(mayRetry, DONE)) {
            curJob = mayRetry;
            return false;
        }
        return true;
    }
}
